<?php
/**
 * 用户处理
 *
 * @author Mo yi <root@imoi.cn>
 * @link   http://www.imoi.cn
 * @copyright Copyright &copy; 2010-2012 DuoLam Software LLC
 * @license http://www.imoi.cn/license/
 * @version $Id: dpUser.php 1 2012-04-22 14:41:54Z Mo.yi $
 * @package db
 * @since 1.0
 */

class dpUser extends dpComponent
{

	/**
	 * 是否自动登陆（将使用cookie）
	 */
	public $autoLogin = false;

	/**
	 * cookie 作用域
	 */
	public $cookieDomain = '';

	/**
	 * 过滤的数据 
	 */
	public $filter = array();

	/**
	 * 游客称号
	 */
	public $guestName = 'guest';

	/**
	 * 登录URL
	 */
	public $loginUrl;

	/**
	 * 超时时间，单位：秒
	 */
	public $userTimeout = 600;

	/**
	 * session or cookie 的识别前缀
	 */
	public $keyPrefix;

	/**
	 * 身份cookie
	 */
	private $_identityCookie;

	/**
	 * 信息存储句柄
	 */
	private $_save;

	/**
	 * 构造方法
	 */
	public function __construct()
	{
		$this->init();
		$this->run();
	}

	/**
	 * 初始方法，可重载实现自定义初始化
	 */
	protected function init(){}

	/**
	 * 用户处理私有初始化
	 */
	public function run()
	{
		if ($this->autoLogin) {
			$this->_save = new dpCookie;
			$this->_identityCookie = $_COOKIE;
		} else {
			$this->_save = new dpSession;
			$this->_save->setTimeOut($this->userTimeout);
		}
		return $this;
	}

	/**
	 * reset 重置用户信息
	 */
	public function reset($data)
	{
		if (empty($this->_save)) $this->run();
		$this->_identityCookie = array();
		if (!empty($data) && is_array($data)) {
			foreach ($data as $name => $val) {
				if ($this->_save->is($name)) {
					$this->setState($name, $val);
					$this->_save->delete($name);
				}
			}
			$this->setOtherState();
			$this->_save(0);
		}
	}

	/**
	 * 用户登陆
	 * @param object $identity 用户身份验证句柄
	 * @param int    $expired  使用cookie登陆，过期时间，单位：天
	 */
	public function login($identity, $expired = 0)
	{
		$id   = $identity->getId();
		$gid  = $identity->getGid();
		$name = $identity->getName();

		if (empty($id)) return false;

		$this->setOtherState();

		if ($this->beforeLogin($id, $gid, $this->getState())) {
			$this->setState('id', $id);
			$this->setState('gid', $gid);
			$this->setState('name', $name);
			$this->_save($expired);
			$this->afterLogin();
		}
	}

	/**
	 * 设置其他信息状态
	 */
	protected function setOtherState()
	{
		$request = new dpRequest;
		$this->setState('lang', $request->getUserLang());
		$this->setState('ip', $request->getUserIp());
		$this->setState('url', $request->getUrlSource());
		$this->setState('browser', $request->getUserBrowser());
		$this->setState('date', time());
		unset($request);
	}

	/**
	 * 用户登陆前执行该方法，重载该方法，实现自定义，该方法必须返回true
	 * 用户状况信息包含(登陆IP，登陆时间，以及该用户的客户端一些信息)
	 * @param int $id 用户ID
	 * @param int $gid 用户组ID
	 * @param array $state 用户基本状况信息
	 * @return boolean
	 */
	protected function beforeLogin($id, $gid, $state)
	{
		return true;
	}

	/**
	 * 用户登陆后执行该方法，重载该方法，实现自定义
	 */
	protected function afterLogin(){}

	/**
	 * 用户退出
	 */
	public function logout()
	{
		if ($this->beforeLogout()) {
			$names = array('id', 'gid', 'name', 'lang', 'ip', 'browaser', 'date');
			foreach ($names as $name) {
				$name = $this->_state($name);
				$this->_save->delete($name, $this->cookieDomain);
			}
			$this->afterLogout();
		}
	}

	/**
	 * 用户退出前执行该方法，可重载自定义
	 * 该方法必须返回 true
	 * @return boolean
	 */
	protected function beforeLogout()
	{
		return true;
	}

	/**
	 * 用户退出后执行该方法，可重载自定义
	 */
	protected function afterLogout(){}

	/**
	 * 检测是否是游客(主要用于判断用户是否登陆)
	 * @return boolean
	 */
	public function isGuest()
	{
		if (empty($this->_save)) $this->run();

		return $this->_save->get($this->_state('id')) ? false : true;
	}

	/**
	 * 获取用户ID
	 * @return int || null
	 */
	public function getId()
	{
		$id = $this->_save->get($this->_state('id'));
		return $id ? $id : null;
	}

	/**
	 * 获取组ID
	 * @return int || null
	 */
	public function getGid()
	{
		$gid = $this->_save->get($this->_state('gid'));
		return $gid ? $gid : null;
	}

	/**
	 * 获取用户名
	 * @return string || null
	 */
	public function getName()
	{
		$name = $this->_save->get($this->_state('name'));
		return $name ? $name : null;
	}

	/**
	 * 保存信息
	 */
	private function _save($expired)
	{
		if ($expired == 0) $expired = null;
		foreach ($this->_identityCookie as $name => $value) {
			if (in_array($name, $this->filter)) continue;
			if ($this->autoLogin)
				$this->_save->set($name, $value, $expired, '/', $this->cookieDomain);
			else
				$this->_save->set($name, $value);
		}
	}

	/**
	 * 获取设置的前缀
	 * @return string
	 */
	public function getKeyPrefix()
	{
		if (empty($this->keyPrefix))
			return md5('Duolam'.get_class($this));
		else
			return md5($this->keyPrefix);
	}

	/**
	 * 设置cookie or session 前缀
	 * @param string $val
	 */
	public function setKeyPrefix($val)
	{
		$this->keyPrefix = $val;
	}

	/**
	 * 封装信息状态
	 * @param string 信息
	 * @return string
	 */
	private function _state($val)
	{
		return $this->getKeyPrefix() . '__'.$val;
	}

	/**
	 * 设置用户状况信息
	 */
	public function setState($name, $value)
	{
		$this->_identityCookie[$this->_state($name)] = $value;
	}

	/**
	 * 临时保存用户一个信息
	 */
	public function tempSaveUserInfo($name, $value)
	{
		$name = $this->_state($name);
		$this->_save->set($name, $value);
	}

	/**
	 * 获取设置的用户状况信息
	 */
	public function getState($name = null)
	{
		if ($name == null) return false;

		if (empty($this->_save)) $this->run();

		if ($name = $this->_save->get($this->_state($name)))
			return $name;
		else
			return false;
	}

	public function __get($name)
	{
		if (empty($name)) return false;

		return $this->getState($name);
	}

	public function __call($name, $params){}

	/**
	 * 获取一个用户的所有信息
	 */
	public function getUser($uid)
	{
		return D::app()->auth()->getUserInfo($uid);
	}

	/**
	 * 检查某个用户是否是超级管理员
	 */
	public function isSuperAdmin($uid)
	{
		$result = D::app()->auth()->getUserInfo($uid, 'is_manage');
		return isset($result['is_manage']) && $result['is_manage'] == 1 ? true : false;
	}

	/**
	 * 检查某个用户是否激活
	 */
	public function isActivation($uid)
	{
		$result = D::app()->auth()->getUserInfo($uid, 'is_activation');
		return isset($result['is_activation']) && $result['is_activation'] == 1 ? true : false;
	}

	public function checkAccess($action, $limit = 'whole' , $cacheing = false)
	{
		$limit = empty($limit) ? 'whole' : $limit;

		if (D::app()->user()->isSuperAdmin($this->getState('id'))) return true;

		if ($cacheing) {
			$actions = D::app()->cache()->get($this->_state('id'));
			if (!$actions) {
				$actions = D::app()->rule()->getBehavior($limit);
				D::app()->cache()->set($this->_state('id'), $actions, 600);
			}
		} else
			$actions = D::app()->rule()->getBehavior($limit);

		if (isset($actions[0]) && $actions[0] == '*') return true;
		
		return in_array($action, $actions) ? true : false;
	}

	function __destruct()
	{
		unset($_save, $_identityCookie);
	}
}
?>